using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Caching;

namespace Toast.Caching
{
    public static class HttpRuntimeCacheService
    {
        static IList<string> _cacheKeys = new List<string>();

        /// <summary>
        /// Gets or inserts and gets the specified cache item.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cacheKey">The cache key.</param>
        /// <param name="getItemCallback">The callback if no cached item is found.</param>
        /// <returns></returns>
        public static T Get<T>(string cacheKey, Func<T> getItemCallback) where T : class
        {
            return Get(cacheKey, getItemCallback, null);
        }

        /// <summary>
        /// Gets or inserts and gets the specified cache item.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cacheKey">The cache key.</param>
        /// <param name="getItemCallback">The callback if no cached item is found.</param>
        /// <param name="cacheDependency">The cache dependency.</param>
        /// <returns></returns>
        public static T Get<T>(string cacheKey, Func<T> getItemCallback, CacheDependency cacheDependency) where T : class
        {
            return Get(cacheKey, getItemCallback, cacheDependency, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration);
        }

        /// <summary>
        /// Gets or inserts and gets the specified cache item.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cacheKey">The cache key.</param>
        /// <param name="getItemCallback">The callback if no cached item is found.</param>
        /// <param name="cacheDependency">The cache dependency.</param>
        /// <param name="absoluteExpiration">The absolute expiration.</param>
        /// <param name="slidingExpiration">The sliding expiration.</param>
        /// <returns></returns>
        public static T Get<T>(string cacheKey, Func<T> getItemCallback, CacheDependency cacheDependency, DateTime absoluteExpiration, TimeSpan slidingExpiration) where T : class
        {
            var key = Convert.ToBase64String(Encoding.UTF8.GetBytes(cacheKey));

            var item = HttpRuntime.Cache.Get(key) as T;

            if (item == null)
            {
                item = getItemCallback();
                HttpContext.Current.Cache.Insert(key, item, cacheDependency, absoluteExpiration, slidingExpiration);
                _cacheKeys.Add(key);
            }
            return item;
        }

        /// <summary>
        /// Removes any owned items from the cache.
        /// </summary>
        public static void Clear()
        {
            foreach (var cacheKey in _cacheKeys)
            {
                HttpRuntime.Cache.Remove(cacheKey);
            }

            _cacheKeys = new List<string>();
        }
    }
}